home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / OWLSRC.PAK / DIALOG.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  18.5 KB  |  763 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1991, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.15  $
  6. //
  7. // Implementation of class TDialog. TDialogs are the base for any type of
  8. // modal or modeless window that loads itself from resource.
  9. //----------------------------------------------------------------------------
  10. #pragma hdrignore SECTION
  11. #include <owl/pch.h>
  12. #if !defined(OWL_DIALOG_H)
  13. # include <owl/dialog.h>
  14. #endif
  15. #if !defined(OWL_APPLICAT_H)
  16. # include <owl/applicat.h>
  17. #endif
  18. # include <string.h>
  19.  
  20. #if defined(BI_COMP_BORLANDC)
  21. # include <bwcc.h>           // Currently only available with Borland C++
  22. #endif
  23.  
  24. OWL_DIAGINFO;
  25. DIAG_DECLARE_GROUP(OwlMsg);  // diagnostic group for message tracing
  26. DIAG_DECLARE_GROUP(OwlWin);  // diagnostic group for windows
  27.  
  28. #if !defined(SECTION) || SECTION == 1
  29.  
  30. #if !defined(RT_DLGINIT)
  31. # define RT_DLGINIT       MAKEINTRESOURCE(240)
  32. #endif
  33.  
  34. //
  35. // Global message id for GetWindowPtr call defined in applicat.cpp
  36. //
  37. extern uint _OWLDATA GetWindowPtrMsgId;
  38.  
  39. //
  40. // Public so derived classes can create  
  41. //
  42. TDialog* _OWLDATA DlgCreationWindow = 0;
  43.  
  44. DEFINE_RESPONSE_TABLE1(TDialog, TWindow)
  45.   EV_WM_CLOSE,
  46.   EV_WM_PAINT,
  47.   EV_WM_CTLCOLOR,
  48.   EV_WM_SETFONT,
  49.   EV_DM_GETDEFID,
  50.   EV_DM_SETDEFID,
  51. #if defined(BI_PLAT_WIN32)
  52.   EV_DM_REPOSITION,
  53. #endif
  54.   EV_COMMAND(IDOK, CmOk),
  55.   EV_COMMAND(IDCANCEL, CmCancel),
  56. END_RESPONSE_TABLE;
  57.  
  58. //
  59. // Constructor for a TDialog object
  60. //
  61. // Takes an TResId for its template name or numeric Id
  62. //
  63. TDialog::TDialog(TWindow* parent, TResId resId, TModule* module)
  64. {
  65.   // Initialize virtual base, in case the derived-most used default ctor
  66.   //
  67.   TWindow::Init(parent, 0, module);
  68.  
  69.   DisableAutoCreate();
  70.   if (HiUint16(uint32(Title)))
  71.     delete[] Title;
  72.   Title = (LPSTR)MAKEINTRESOURCE(0xFFFF); // Title setting--"don't-change"
  73.  
  74.   SetFlag(wfFromResource);
  75.   ClearFlag(wfDeleteOnClose);
  76.  
  77.   DialogAttr.Param = 0;
  78.   IsModal = false;
  79.   DialogAttr.Name = resId.IsString() ? strnewdup(resId) : (char far*)resId;
  80. }
  81.  
  82. //
  83. // Destructor for a TDialog
  84. //
  85. TDialog::~TDialog()
  86. {
  87.   if (HiUint16(uint32(DialogAttr.Name)))
  88.     delete[] DialogAttr.Name;
  89. }
  90.  
  91. //
  92. // Preprocess posted messages to provide various accelerator translations.
  93. // Handles normal window accelerators, MDI accelerators & dialog accelerators
  94. //
  95. bool
  96. TDialog::PreProcessMsg(MSG& msg)
  97. {
  98.   // Processed any accelerators associated with this window
  99.   //
  100.   if (TWindow::PreProcessMsg(msg))
  101.     return true;
  102.  
  103.   // See if we are in an mdi child, & try mdi accelerator translation if so
  104.   //
  105.   THandle child;
  106.   THandle client;
  107.   if ((child = GetParentH()) != 0 &&
  108.       (client = ::GetParent(child)) != 0 &&
  109.       child == (THandle)::SendMessage(client, WM_MDIGETACTIVE, 0, 0) &&
  110.       ::TranslateMDISysAccel(client, &msg))
  111.     return true;
  112.  
  113.   // Do dialog accelerator translation last, since it tends to eat other
  114.   // accelerators
  115.   //
  116.   return ::IsDialogMessage(GetHandle(), &msg);
  117. }
  118.  
  119. //
  120. // Override TWindow virtual in order to supply the classname for Windows class
  121. // registration. Handles BWCC and native dialog classnames.
  122. //
  123. char far*
  124. TDialog::GetClassName()
  125. {
  126. #if defined(BI_COMP_BORLANDC)
  127.   if (GetApplication()->BWCCEnabled())
  128.     return BORDLGCLASS;
  129.   else
  130. #endif
  131.     return (char far*)WC_DIALOG;
  132. }
  133.  
  134. //
  135. // Override TWindow virtual in order to fill in the appropriate information
  136. // in the WNDCLASS structure. Handles BWCC and native dialogs, retrieving the
  137. // default class information from those existing classes.
  138. //
  139. void
  140. TDialog::GetWindowClass(WNDCLASS& wndClass)
  141. {
  142.   TResId dlgClass;
  143.  
  144. #if defined(BI_COMP_BORLANDC)
  145.   if (GetApplication()->BWCCEnabled()) {
  146.     GetApplication()->GetBWCCModule()->Register(*GetModule());
  147.     dlgClass = BORDLGCLASS;
  148.   }
  149.   else
  150. #endif
  151.     dlgClass = WC_DIALOG;
  152.  
  153.   if (!TUser::GetClassInfo(0, dlgClass, &wndClass))
  154.     GetModule()->GetClassInfo(dlgClass, &wndClass);
  155.  
  156.   wndClass.lpszClassName = GetClassName();
  157.   wndClass.hInstance = *GetModule();   
  158. }
  159.  
  160. //
  161. // Handler for WM_SETFONT, is dispatched from DialogFunction() once
  162. // during dialog creation. Subsequent dispatched are done normally.
  163. //
  164. void
  165. TDialog::EvSetFont(HFONT /*hFont*/, bool /*redraw*/)
  166. {
  167.   if (IsFlagSet(wfFullyCreated))
  168.     DefaultProcessing();
  169. }
  170.  
  171. //
  172. // Handler for WM_PAINT. Rerout this message back to the underlying dialog to
  173. // keep TWindow::EvPaint from eating it.
  174. //
  175. void
  176. TDialog::EvPaint()
  177. {
  178.   DefaultProcessing();
  179. }
  180.  
  181. //
  182. // If this app is using Ctl3d, forward the WM_CTLCOLOR message to the
  183. // ctl3d.dll since it needs to handle that & we don't let it autosubclass
  184. //
  185. HBRUSH
  186. TDialog::EvCtlColor(HDC hDC, THandle hChild, uint ctlType)
  187. {
  188.   if (GetApplication()->Ctl3dEnabled()) {
  189. #if defined(BI_PLAT_WIN32)
  190.     HBRUSH hBr = GetApplication()->GetCtl3dModule()->
  191.           CtlColorEx(WM_CTLCOLORMSGBOX+ctlType, TParam1(hDC), TParam2(hChild));
  192. #else
  193.     HBRUSH hBr = GetApplication()->GetCtl3dModule()->
  194.           CtlColorEx(WM_CTLCOLOR, TParam1(hDC), MkParam2(uint16(hChild), ctlType));
  195. #endif
  196.  
  197.     if (hBr)
  198.       return hBr;
  199.   }
  200.   return TWindow::EvCtlColor(hDC, hChild, ctlType);
  201. }
  202.  
  203. //
  204. // Return the default Id.
  205. // High word must be DC_HASDEFID.
  206. //
  207. uint32
  208. TDialog::EvGetDefId()
  209. {
  210.   return DefaultProcessing();
  211. }
  212.  
  213. //
  214. // Set the pushbutton with identifier id the default button for the dialog.
  215. //
  216. bool
  217. TDialog::EvSetDefId(int /*id*/)
  218. {
  219.   return (bool)DefaultProcessing();
  220. }
  221.  
  222. #if defined(BI_PLAT_WIN32)
  223. //
  224. // Reposition the dialog so that it fits within the desktop area
  225. //
  226. void
  227. TDialog::EvReposition()
  228. {
  229.   DefaultProcessing();
  230. }
  231. #endif
  232.  
  233. //
  234. // The default dialog function. Handles the two mesages, WM_INITDIALOG and
  235. // WM_SETFONT that may be passed to us without sending, or sent before we get
  236. // a chance to thunk DIALOG's window proc.
  237. //
  238. // EvInitDialog is called as a virtual function, while EvSetFont is dispatched
  239. // to.
  240. //
  241. bool
  242. TDialog::DialogFunction(uint msg, TParam1 param1, TParam2 param2)
  243. {
  244.   TRACEX(OwlMsg, 2, MsgName(msg) << "(DlgFcn)=> " << *this);
  245.  
  246.   switch (msg) {
  247.  
  248.     // 'Dispatch' WM_INITDIALOG by making a virtual call--no response table
  249.     // used. This is not generally overriden, and only arrives once.
  250.     //
  251.     case WM_INITDIALOG:
  252.       return EvInitDialog((THandle)param1);
  253.  
  254.     // Dispatch WM_SETFONT only for the first, non-sent occurance. Subsequent
  255.     // WM_SETFONTs will be dispatched normally in TWindow.
  256.     //
  257.     case WM_SETFONT:
  258.       if (!IsFlagSet(wfFullyCreated)) {
  259.         TEventInfo  eventInfo(msg);
  260.         if (Find(eventInfo)) {
  261.           return Dispatch(eventInfo, param1, param2) == 0;
  262.         }
  263.       }
  264.       return true;
  265.  
  266.     // Catch these few messages here & forward to the ctrl3d dll if it is
  267.     // loaded and enabled.
  268.     //
  269.     case WM_SETTEXT:
  270.     case WM_NCPAINT:
  271.     case WM_NCACTIVATE:
  272.       if (GetApplication()->Ctl3dEnabled()) {
  273.         SetMsgResult(GetApplication()->GetCtl3dModule()->
  274.           DlgFramePaint(GetHandle(), msg, param1, param2));
  275.       }
  276.       break;
  277.   }
  278.   return false;  // Not handled
  279. }
  280.  
  281. //
  282. // Handles messages that comes from WC_DIALOG's wndProc
  283. //
  284. // If DlgCreationWindow is not 0, then msg is destined for DlgCreationWindow.
  285. // Setup DlgCreationWindow's GetHandle(), subclass the WC_DIALOG class's window
  286. // function. Calls the virtual DialogFunction() to handle specific messages,
  287. // mostly for startup sequence.
  288. //
  289. /*OWL_EXPORT*/ int CALLBACK OWL_EXPORT16
  290. TDialog::StdDlgProc(THandle hDlg, uint msg, TParam1 param1, TParam2 param2)
  291. {
  292.   // Thunk on first message to a non-thunked window & thats not one sent to
  293.   // parent dialogs.
  294.   //
  295.   if (msg == GetWindowPtrMsgId) // if it gets here, we wont know how to get it
  296.     return false;
  297.  
  298.   // Get the window ptr using the global version since there is no other
  299.   // context.
  300.   //
  301. #if defined(BI_NAMESPACE)
  302.   TWindow*  w = OWL::GetWindowPtr(hDlg);
  303. #else
  304.   TWindow*  w = ::GetWindowPtr(hDlg);
  305. #endif
  306.   TDialog*  dialog = TYPESAFE_DOWNCAST(w, TDialog);
  307.  
  308.   if (DlgCreationWindow && !dialog && msg != WM_CANCELMODE && msg != WM_ENABLE) {
  309.     DlgCreationWindow->SetHandle(hDlg);
  310.  
  311.     DlgCreationWindow->SubclassWindowFunction();
  312.     dialog = DlgCreationWindow;
  313.     DlgCreationWindow = 0;
  314.   }
  315.   if (!dialog)
  316.     return false;
  317.  
  318.   // Handle all messages once thunked.
  319.   // Call the virtual DialogFunction() to handle specific messages
  320.   //
  321. #if defined(BI_PLAT_WIN32)
  322.   if (TSystem::SupportsExceptions())
  323.     return dialog->DialogFunction(msg, param1, param2);
  324. #endif
  325. #if defined(BI_PLAT_WIN16) || defined(WIN32S_SUPPORT)
  326.   TRY {
  327.     return dialog->DialogFunction(msg, param1, param2);
  328.   }
  329.   CATCH( (TXOwl& x) {
  330.     w->GetApplication()->SuspendThrow(x);
  331.   })
  332.   CATCH( (xalloc& x) {
  333.     w->GetApplication()->SuspendThrow(x);
  334.   })
  335.   CATCH( (xmsg& x) {
  336.     w->GetApplication()->SuspendThrow(x);
  337.   })
  338. #if !defined(BI_NO_NEW_CASTS)
  339.   CATCH( (Bad_cast) {
  340.     w->GetApplication()->SuspendThrow(TApplication::xsBadCast);
  341.   })
  342.   CATCH( (Bad_typeid) {
  343.     w->GetApplication()->SuspendThrow(TApplication::xsBadTypeid);
  344.   })
  345. #endif
  346.   CATCH( (...) {
  347.     w->GetApplication()->SuspendThrow(TApplication::xsUnknown);
  348.   })
  349. #endif
  350.  
  351.   // When exceptions are disabled CATCH is defined as empty, so the only code
  352.   // is the TRY block, making this return unreachable
  353.   //
  354. #pragma warn -rch
  355.   return true;  // default value returned when exception caught
  356. #pragma warn .rch
  357. }
  358.  
  359. //
  360. //
  361. //
  362. static bool
  363. RegisterFails(TWindow* win, void*)
  364. {
  365.   return !win->Register();
  366. }
  367.  
  368. // Register all the dialog's child objects (for custom control support)
  369. //
  370. void
  371. TDialog::RegisterChildObjects()
  372. {
  373.   if (FirstThat(RegisterFails))
  374.     TXWindow::Raise(this, IDS_CHILDREGISTERFAIL);
  375. }
  376.  
  377. //
  378. // Creates an Windows modeless dialog and associates the modeless dialog
  379. // interface element with the TDialog
  380. //
  381. bool
  382. TDialog::Create()
  383. {
  384.   PRECONDITION(GetHandle() == 0);
  385.  
  386.   IsModal = false;
  387.  
  388.   if (!Register())
  389.     TXWindow::Raise(this, IDS_CLASSREGISTERFAIL);
  390.  
  391.   DlgCreationWindow = this;
  392.  
  393.   LoadAcceleratorTable();
  394.  
  395.   // Register all the dialog's child objects (for custom control support)
  396.   //
  397.   RegisterChildObjects();
  398.  
  399.   SetHandle(DoCreate());
  400.   GetApplication()->ResumeThrow();
  401.   if (!GetHandle())
  402.     TXWindow::Raise(this, IDS_WINDOWCREATEFAIL);
  403.  
  404.   GetHWndState();
  405.   return true;
  406. }
  407.  
  408. //
  409. // Overriden TWindow virtual to create & return the actual Handle for this
  410. // dialog.
  411. //
  412. TWindow::THandle
  413. TDialog::DoCreate()
  414. {
  415.   return ::CreateDialogParam(*GetModule(), DialogAttr.Name,
  416.                              Parent? Parent->GetHandle() : 0,
  417.                              (DLGPROC)StdDlgProc,
  418.                              DialogAttr.Param);
  419. }
  420.  
  421. //
  422. // Creates an modal dialog and associates the modal dialog interface
  423. // element with the TDialog.  Registers all the dialog's child objects
  424. // (for custom control support).  If this registering fails, throws TXWindow
  425. // exception.  If the dialog fails to execute, throw a TXWindow exception.
  426. // Returns the return value from the dialog manager.
  427. //
  428. int
  429. TDialog::Execute()
  430. {
  431.   PRECONDITION(GetHandle() == 0);
  432.  
  433.   IsModal = true;
  434.  
  435.   if (!Register())
  436.     TXWindow::Raise(this, IDS_CLASSREGISTERFAIL);
  437.  
  438.   DlgCreationWindow = this;
  439.  
  440.   // Register all the dialog's child objects (for custom control support)
  441.   //
  442.   RegisterChildObjects();
  443.  
  444.   int retValue = DoExecute();
  445.   GetApplication()->ResumeThrow();
  446.  
  447.   // DoEcecute returns -1 if it could not create the dialog box
  448.   //
  449.   if (retValue == -1)
  450.     TXWindow::Raise(this, IDS_WINDOWEXECUTEFAIL);
  451.  
  452.   return retValue;
  453. }
  454.  
  455. //
  456. //
  457. // Overriden TWindow virtual to modaly execute this dialog & return the result.
  458. //
  459. int
  460. TDialog::DoExecute()
  461. {
  462.   return ::DialogBoxParam(*GetModule(), DialogAttr.Name,
  463.                           Parent ? Parent->GetHandle() : 0,
  464.                           (DLGPROC)StdDlgProc,
  465.                           DialogAttr.Param);
  466. }
  467.  
  468. //
  469. // Perform resource directed initialization of controls. Uses RT_DLGINIT
  470. // resource with an id matching this dialog's as structured message packets
  471. // to send to controls.
  472. //
  473. // Returns true if successful, or nothing to be done.
  474. //
  475. bool
  476. TDialog::PerformDlgInit()
  477. {
  478.   int rslt = (int)SendMessage(WM_VBXINITFORM, TParam1(GetHandle()),
  479.                               TParam2(DialogAttr.Name));
  480.   if (rslt)
  481.     return rslt > 0;
  482.  
  483.   bool ok = true;
  484.  
  485. #if defined(BI_COMP_BORLANDC)
  486.   if (DialogAttr.Name) {
  487.     HRSRC hRes = GetModule()->FindResource(DialogAttr.Name, RT_DLGINIT);
  488.     if (hRes) {
  489.       HGLOBAL hDat = GetModule()->LoadResource(hRes);
  490.       if (hDat) {
  491.         char HUGE* res = (char HUGE*)::LockResource(hDat);
  492.         if (res) {
  493.           while (ok && *res) {
  494.             uint16 idCtl = *((uint16 far*)res)++;
  495.             uint16 msg = *((uint16 far*)res)++;
  496.             uint32 len = *((uint32 far*)res)++;
  497.  
  498.             if (SendDlgItemMessage(idCtl, msg, 0, TParam2(res)) == -1)
  499.               ok = false;
  500.             res += len;
  501.           }
  502. #if !defined(BI_PLAT_WIN32)
  503.           ::UnlockResource(hDat);
  504. #endif
  505.         }
  506. #if !defined(BI_PLAT_WIN32)
  507.         ::FreeResource(hDat);
  508. #endif
  509.         GetApplication()->ResumeThrow();
  510.       }
  511.     }
  512.   }
  513. #endif
  514.   return ok;
  515. }
  516.  
  517. //
  518. // Virtual handler for WM_INITDIALOG message, called from DialogFunction()
  519. //
  520. // This message is sent after an Windows dialog is created and before the
  521. // dialog is displayed
  522. //
  523. // Calls SetupWindow() to perform setup for the dialog
  524. //
  525. bool
  526. TDialog::EvInitDialog(THandle /*hFocus*/)
  527. {
  528.   GetHWndState();
  529.   PerformDlgInit();
  530.   SetupWindow();
  531.   SetFlag(wfFullyCreated);
  532.   return true;  // have Windows set focus to "hFocus"
  533. }
  534.  
  535. //
  536. // Sets up the dialog box by calling setting up Ctl3d if enabled, then
  537. // calling SetCaption() and then TWindow::SetupWindow()
  538. //
  539. // Calling SetCaption() here allows us to override the dialog caption
  540. // (specified in the dialog resource) by setting Title prior to this point
  541. //
  542. void
  543. TDialog::SetupWindow()
  544. {
  545.   // If this app is using Ctl3d, tell it to explicitly subclass this dialog's
  546.   // controls (CTL3D_ALL). Its better to do this here than enable
  547.   // autosubclassing since that requires a CBT hook set all the time which
  548.   // slows the app considerably.
  549.   //
  550.   if (GetApplication()->Ctl3dEnabled())
  551.     GetApplication()->GetCtl3dModule()->SubclassDlg(*this, 0xFFFF);
  552.  
  553.   SetCaption(Title);
  554.   TWindow::SetupWindow();
  555. }
  556.  
  557. //
  558. // Conditionally shuts down the dialog box
  559. //
  560. // If this is a modal dialog calls CanClose() and, if CanClose() returns true,
  561. // transfers its data and shuts down, passing retValue (default IDCANCEL)
  562. //
  563. // Calls TWindow::CloseWindow(retValue) if this is a modeless dialog
  564. //
  565. void
  566. TDialog::CloseWindow(int retValue)
  567. {
  568.   if (IsModal) {
  569.     if (CanClose()) {
  570.       TransferData(tdGetData);
  571.       Destroy(retValue);
  572.     }
  573.   }
  574.   else {
  575.     TWindow::CloseWindow(retValue);
  576.   }
  577. }
  578.  
  579. //
  580. // Destroys the Handle associated with the TDialog
  581. //
  582. void
  583. TDialog::Destroy(int retValue)
  584. {
  585.   if (IsModal && GetHandle()) {
  586.     ForEach(DoEnableAutoCreate);
  587.     ::EndDialog(GetHandle(), retValue);
  588.   }
  589.   else {
  590.     TWindow::Destroy(retValue);
  591.   }
  592. }
  593.  
  594. //
  595. // Set Dialog's Title data member and Caption. This is non-virtual, but is
  596. // always called with a TDialog or more derived pointer.
  597. //
  598. void
  599. TDialog::SetCaption(const char far* title)
  600. {
  601.   if (HiUint16(uint32(title)) && LoUint16(uint32(title)) != 0xFFFF)
  602.     TWindow::SetCaption(title);
  603. }
  604.  
  605. //
  606. // Responds to an incoming notification message from a button with
  607. // an Id equal to IDOK
  608. //
  609. void
  610. TDialog::CmOk()
  611. {
  612.   CloseWindow(IDOK);
  613.  
  614.   if (!IsModal  && !GetHandle() && IsFlagSet(wfDeleteOnClose))
  615.     GetApplication()->Condemn(this);
  616. }
  617.  
  618. //
  619. // Responds to an incoming notification message from a button with
  620. // an Id equal to IDCANCEL. Unconditionally destroy the window.
  621. //
  622. void
  623. TDialog::CmCancel()
  624. {
  625.   EvClose();
  626. }
  627.  
  628. //
  629. // Message response function for WM_CLOSE by unconditionally closing
  630. // the window.
  631. //
  632. void
  633. TDialog::EvClose()
  634. {
  635.   Destroy(IDCANCEL);
  636.  
  637.   if (!IsModal && !GetHandle() && IsFlagSet(wfDeleteOnClose))
  638.     GetApplication()->Condemn(this);
  639. }
  640.  
  641.  
  642. //
  643. // Initialize the base class
  644. //
  645. TControlEnabler::TControlEnabler(uint id, HWND hWndReceiver)
  646. :
  647.   TCommandEnabler(id, hWndReceiver)
  648. {
  649. }
  650.  
  651. //
  652. // Enable/Disable the control
  653. //
  654. void
  655. TControlEnabler::Enable(bool enable)
  656. {
  657.   ::EnableWindow(GetReceiver(), enable);
  658.   TCommandEnabler::Enable(enable);
  659. }
  660.  
  661. //
  662. // Set the text of the control
  663. //
  664. void
  665. TControlEnabler::SetText(const char far* text)
  666. {
  667.   ::SetWindowText(GetReceiver(), text);
  668. }
  669.  
  670. //
  671. // Use with only buttons!
  672. //
  673. void
  674. TControlEnabler::SetCheck(int check)
  675. {
  676.   ::SendMessage(GetReceiver(), BM_SETCHECK, check, 0);
  677. }
  678.  
  679. //
  680. // Iterate over each child control and routes the command enabler.
  681. // Does not rely on an OWL interface object to work.
  682. //
  683. bool
  684. TDialog::IdleAction(long idleCount)
  685. {
  686.   TWindow::IdleAction(idleCount);
  687.  
  688.   if (idleCount == 0) {
  689.     HWND child = GetWindow(GW_CHILD);
  690.     while (::IsWindow(child)) {
  691. #if defined(BI_PLAT_WIN32)
  692.       int id = ::GetWindowLong(child, GWL_ID);
  693. #else
  694.       int id = ::GetWindowWord(child, GWW_ID);
  695. #endif
  696.       TControlEnabler ce(id, child);
  697.       RouteCommandEnable(*this, ce);
  698.       child = ::GetWindow(child, GW_HWNDNEXT);
  699.     }
  700.   }
  701.   return false;
  702. }
  703.  
  704. //
  705. // Set focus within a dialog to a specific control.
  706. //
  707. void
  708. TDialog::SetControlFocus(HWND hwnd)
  709. {
  710.   CHECK(hwnd);
  711.   SendMessage(WM_NEXTDLGCTL, TParam1(hwnd), 1);
  712. }
  713.  
  714. //
  715. // Set the focus to either the previous control with WS_TABSTOP or
  716. // the next control with WS_TABSTOP.
  717. //
  718. void
  719. TDialog::SetControlFocus(THow how)
  720. {
  721.   SendMessage(WM_NEXTDLGCTL, (how == Next) ? 1 : 0, 0);
  722. }
  723.  
  724.  
  725. #endif
  726. #if !defined(SECTION) || SECTION == 2
  727.  
  728. IMPLEMENT_STREAMABLE1(TDialog, TWindow);
  729.  
  730. #if !defined(BI_NO_OBJ_STREAMING)
  731.  
  732. //
  733. // Reads an instance of TDialog from the passed ipstream
  734. //
  735. void*
  736. TDialog::Streamer::Read(ipstream& is, uint32 /*version*/) const
  737. {
  738.   ReadBaseObject((TWindow*)GetObject(), is);
  739.  
  740.   is >> (TResId&)GetObject()->DialogAttr.Name;
  741.   is >> GetObject()->IsModal;
  742.   return GetObject();
  743. }
  744.  
  745. #if !defined(BI_NO_OBJ_STREAMING)
  746.  
  747. //
  748. // Writes the TDialog to the passed opstream
  749. //
  750. void
  751. TDialog::Streamer::Write(opstream& os) const
  752. {
  753.   WriteBaseObject((TWindow*)GetObject(), os);
  754.  
  755.   os << TResId(GetObject()->DialogAttr.Name);
  756.   os << GetObject()->IsModal;
  757. }
  758. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  759.  
  760. #endif  // if !defined(BI_NO_OBJ_STREAMING)
  761.  
  762. #endif
  763.